

package com.xgit.iov.admin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xgit.iov.admin.mapper.SysDeptMapper;
import com.xgit.iov.admin.service.SysDeptService;
import com.xgit.iov.common.core.constant.CommonConstants;
import com.xgit.iov.common.core.entity.SysDept;
import com.xgit.iov.common.core.model.DeptTree;
import com.xgit.iov.common.core.model.TreeUtil;
import com.xgit.iov.common.core.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门管理 服务实现类
 * </p>
 *
 * @author lengleng
 * @since 2019/2/1
 */
@Service
@RequiredArgsConstructor
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {


	/**
	 * 添加信息部门
	 *
	 * @param sysDept 部门
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveDept(SysDept sysDept) {
		SysDept baseDept = baseMapper.selectById(sysDept.getParentId());

		if (ObjectUtil.isNotNull(baseDept)){
			sysDept.setParentIds(baseDept.getParentIds() + "," + sysDept.getParentId());
		} else {
			sysDept.setParentIds(String.valueOf(CommonConstants.DEPT_TREE_ROOT_ID));
		}

		this.save(sysDept);
		return Boolean.TRUE;
	}


	/**
	 * 删除部门
	 *
	 * @param id 部门 ID
	 * @return 成功、失败
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean removeDeptById(Long id) {
		// 查询父节点为当前节点的节点
		List<SysDept> deptList = this.list(Wrappers.<SysDept>query()
			.lambda().eq(SysDept::getParentId, id));

		if (deptList != null && deptList.size() != 0){
			throw new IllegalArgumentException("机构含有下级不能删除");
		}

		if (ObjectUtil.isNotEmpty(id)) {
			this.removeById(id);
		}
		return Boolean.TRUE;
	}

	/**
	 * 更新部门
	 *
	 * @param sysDept 部门信息
	 * @return 成功、失败
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean updateDeptById(SysDept sysDept) {

		SysDept newParentDept = baseMapper.selectById(sysDept.getParentId());
		SysDept oldDept = baseMapper.selectById(sysDept.getId());
		if (ObjectUtil.isNotNull(newParentDept) && ObjectUtil.isNotNull(oldDept)) {
			String newAncestors = newParentDept.getParentIds() + "," + newParentDept.getId();
			String oldAncestors = oldDept.getParentIds();
			sysDept.setParentIds(newAncestors);
			updateDeptChildren(sysDept.getId(), newAncestors, oldAncestors);
		}

		//更新部门状态
		this.updateById(sysDept);
		return Boolean.TRUE;
	}

	/**
	 * 修改子元素关系
	 *
	 * @param deptId 被修改的部门ID
	 * @param newAncestors 新的父ID集合
	 * @param oldAncestors 旧的父ID集合
	 */
	public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
		List<SysDept> children = baseMapper.selectChildrenDeptById(deptId);
		for (SysDept child : children) {
			child.setParentIds(child.getParentIds().replace(oldAncestors, newAncestors));
		}
		if (children.size() > 0) {
			baseMapper.updateDeptChildren(children);
		}
	}

	/**
	 * 查询全部部门树
	 *
	 * @return 树
	 */
	@Override
	public List<DeptTree> listDeptTrees(SysDept sysDept) {
		if (!sysDept.isLazy()) {
			return getDeptTree(baseMapper.selectList(Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotEmpty(sysDept.getName()), SysDept::getName,sysDept.getName())
				.orderByAsc(SysDept::getSort)), CommonConstants.DEPT_TREE_ROOT_ID);
		}

//		Long parentId = sysDept.getParentId() == null ? CommonConstants.DEPT_TREE_ROOT_ID : sysDept.getParentId();
		return getDeptTree(baseMapper.lazyList(sysDept), CommonConstants.DEPT_TREE_ROOT_ID);
	}

	/**
	 * 查询全部部门树
	 *
	 * @return 树
	 */
	@Override
	public List<DeptTree> listDept(Long tenantId) {
		if (ObjectUtil.isNull(tenantId)){
			tenantId = SecurityUtils.getUser().getTenantId();
		}
		return baseMapper.listDeptTrees(tenantId);
	}

	/**
	 * 查询用户部门树
	 *
	 * @return
	 */
	@Override
	public List<DeptTree> listCurrentUserDeptTrees() {
		Long deptId = SecurityUtils.getUser().getDeptId();
		List<SysDept> deptList = baseMapper
			.selectList(Wrappers.<SysDept>query().lambda()
				.eq(SysDept::getParentId, deptId));
		return getDeptTree(deptList,0L);
	}

	/**
	 * 构建部门树
	 *
	 * @param depts 部门
	 * @return
	 */
	private List<DeptTree> getDeptTree(List<SysDept> depts, Long root) {
		List<DeptTree> treeList = depts.stream()
			.filter(dept -> !dept.getId().equals(dept.getParentId()))
			.sorted(Comparator.comparingInt(SysDept::getSort))
			.map(dept -> {
				DeptTree node = new DeptTree();
				node.setId(dept.getId());
				node.setParentId(dept.getParentId());
				node.setName(dept.getName());
				node.setLinkman(dept.getLinkman());
				node.setContact(dept.getContact());
				node.setAddress(dept.getAddress());
				node.setTenantId(dept.getTenantId());
				node.setUpdateTime(dept.getUpdateTime());
				if (ObjectUtil.isNotEmpty(dept.getHasChildren()) && dept.getHasChildren()){
					node.setHasChildren(true);
				}
				return node;
			}).collect(Collectors.toList());
		return TreeUtil.build(treeList, root);
	}
}
